///////////////////////////////////////////////////////////////////////////////
//
// Licensed under the MIT License
//
// Copyright (c) 2010 Chris Colinsky
// All Rights Reserved
//
// version	0.5
// http://code.google.com/p/sugarcookie/
// http://code.google.com/p/sugarcookie/wiki/License
//
////////////////////////////////////////////////////////////////////////////////

package sugarcookie.collections {
	import mx.collections.ArrayCollection;
	import mx.collections.IViewCursor;
	import mx.logging.ILogger;
	import mx.logging.Log;
	import sugarcookie.error.ApplicationError;
	
	/**
	 * EnhancedArrayCollection
	 * Builds on the Flex ArrayCollection to provide functionality for associative arrays.
	 */
	public class EnhancedArrayCollection extends ArrayCollection {
		private var _log:ILogger;
		private var _cursor:IViewCursor;
		
		public function EnhancedArrayCollection(source:Array=null) {
			super(source);
			_log = Log.getLogger("sugarcookie.collections.EnhancedArrayCollection");
		}
		
		// TODO: store indexed list of items as then are added so that associative arrays can be used with the cursor
		override public function createCursor():IViewCursor {
			if (_cursor==null) _cursor = new EnhancedCursor(this);
			return _cursor;
		}
		
		public function addItemWithKey(key:String,val:Object): void {
			if (!isNaN(parseInt(key))) throw new ApplicationError("Key evaluates to a number.");
			
			if (source[key]) _log.warn("key already exists: "+key);
			else source[key] = val;
		}
	
		public function setItemAtKey(val:Object,key:String) : void {
			if (isAssociative()) source[key] = val;
		}
	
		public function getItemAtKey(key:String):Object {
			if (!isAssociative()) {
				_log.warn("ArrayCollection source is indexed and con not accept a string as a key.");
				return null;
			}
			return source[key]!=undefined?source[key]:null;
		}
		
		public function removeItemAtKey(key:String):Object {
			if (!isAssociative()) {
				_log.warn("ArrayCollection source is indexed and con not accept a string as a key.");
				return null;
			}
			var tmp:Object = source[key];
			source[key] = null;
			delete source[key];
			return tmp;
		}
		
		override public function removeAll():void {
			if (isAssociative()) {
				for (var i:String in source) {
					delete source[i];
				}
			} else {
				for (var n:int=0;n<source.length;n++) {
					delete source[n];
				}
			}
		}
		
		public function containsKey(key:String):Boolean {	
			var status:Boolean = false;
			
			for (var i:String in source) {
				if (i == key) status = true;
			}
			return status;
		}
		
		public function isAssociative() : Boolean {
			if (source.length==0) return true;
			else return false;
		}
		
	}
}